package cn.tedu.net.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//本类用于测试自定义注解
public class TestAnnotation {

}

//定义自定义注解,注解名为:Test 注解的语法和Java的语法不同不要混为一谈
/*注解名定义的时候需要使用"@Interface注解名"的方式定义
* 通过@Target注解(需要导包)表示此自定义注解可以使用的位置
* 通过ElementType的静态常量值可以指定自定义注解使用的位置
* 如果有多个值,可以使用{xxx,xxx}@Target({ElementType.METHOD,ElementType.TYPE})的格式来写
* 通过@Retention注解表示生命周期(也需要导包) 通过RetentionPolicy.静态常量来确定此定义注解的生命周期,不能写多个
* 也就是指自定义注解可以存活到哪个阶段,源文件/字节码文件/运行时 只能三选一不能选多个
* */
@Target({ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})//表示此注解可以用来标记方法
@Retention(RetentionPolicy.SOURCE)
@interface Test{
/*
* 自定义注解还可以添加功能--给注解添加属性
* 注意int age();不是方法的定义,而是自定义注解中定义属性age的语法
* 如果为了使用时方便还可以给属性设置默认值,这样就可以直接使用
*  格式: "int age() default 0;"
* */
    int age() default 0;
 /*注解中还可以添加功能,可以定义特殊属性value()
 * 定义方式和别的属性的定义方式一样,只是使用方式不同
 * 我们使用此属性赋值的时候可以不用写成"@Test(value="apple")
 * 格式可以简化成@Test("lemon")
 * 但是在自定义注解类中默认值的赋值不能简写
 * 如果自定义了默认值,使用时可以不用赋值直接使用属性的默认值
 * */
    String value() default "null";
}
//定义一个类 用来测试自定义注解
//@Test
class TestAnno{
    /*测试一:给TestAnno类 name属性 eat()都添加了@Test注解,方法不报错
    * 所以自定义注解能够加在什么位置取决于@Target的值
    * 测试二:修改@Target({ElementType.METHOD,ElementType.TYPE,ElementType.FIELD})
    * 结论:@Test注解可以有多个位置,也就是多个值,格式{,},@Target底层维护的是ElementType数组
    * 测试三:添加了age属性以后@Test注解报错
    * 结论:当自定义注解没有定义属性时,可以直接使用,如果有熟悉了,就必须给属性赋值
    * 测试四:给@Test注解的age属性赋值以后,就不报错了
    * 结论:给属性赋值时的格式"@Test(age=10)",注意,不能直接写10这种错误格式
    * 测试五:给属性赋予默认值后,还可以不加属性值直接使用,此时属性值就是默认值
    * 测试六:我们给特殊属性value赋值的时候可以简写,相当于value="apple"
    * 测试七:因为已经有了默认值,所以不用给特殊属性value赋值直接使用
    * */

//    @Test
    public void eat(){
        System.out.println("吃饭");
    }
    @Test
    String name;
}